﻿using System;
using System.Collections.Generic;
using System.IO;

namespace Jayden.Dll.Core.IO
{
	public class CsvStream : IDisposable
	{
		private System.IO.Stream m_Stream;
		private System.IO.TextReader m_Reader;
		private char m_Separator = ',';
		private char m_Enclosing = '"';

		public CsvStream(System.IO.Stream stream)
		{
			m_Stream = stream;
			m_Reader = new System.IO.StreamReader(m_Stream);
		}

		public CsvStream(string path) : this(File.OpenRead(path)) { }

		public string[] ParseCsvLine(string line)
		{
			if (line == null)
				return null;
			int index = 0;
			List<string> values = new List<string>();
			while (index < line.Length)
			{
				string value = Parse(line, ref index);
				if (value != null)
					values.Add(value);
			}
			return values.ToArray();
		}

		public string[] ReadCsvLine()
		{
			string line = m_Reader.ReadLine();
			return ParseCsvLine(line);
		}

		private void PassWhiteSpaces(string line, ref int index)
		{
			while (index < line.Length && char.IsWhiteSpace(line[index]))
				index++;
		}

		private string ParseEnclosed(string line, ref int index, char enclosing)
		{
			int startIndex = index;
			while (index < line.Length && (line[index] != enclosing || (index + 1 < line.Length && line[index + 1] == enclosing)))
			{
				if (line[index] == enclosing)
					index++;
				index++;
			}
			string text = line.Substring(startIndex, index - startIndex).Replace("" + enclosing + enclosing, "" + enclosing);
			index++;
			PassWhiteSpaces(line, ref index);
			if (index < line.Length && line[index] == m_Separator)
			{
				index++;
				return text;
			}
			return text;
		}

		private string Parse(string line, ref int index)
		{
			PassWhiteSpaces(line, ref index);
			int startIndex = index;
			if (line[index] == m_Enclosing)
			{
				index++;
				return ParseEnclosed(line, ref index, m_Enclosing);
			}
			while (index < line.Length && line[index] != m_Separator)
				index++;
			string value = line.Substring(startIndex, index - startIndex).Trim();
			index++;
			return value;
		}

		public void Dispose()
		{
			if(m_Stream != null)
				m_Stream.Flush();
			if(m_Reader != null)
				m_Reader.Dispose();
			if(m_Stream != null)
				m_Stream.Dispose();
			m_Stream = null;
			m_Reader = null;
		}
	}
}
